package com.tech.cloudapp.util;

import com.tech.cloudapp.consta.CommConst;
import com.tech.cloudapp.exception.BusinessException;
import com.tech.cloudapp.model.CommonResponseDO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

public class JwtUtil {

    public final static String secretKey =  "6AA5FC5F2102193EF128892C0D95D396";
    private final static long jwtExpiration = 604800000; // 7天，单位是毫秒

    // 从token中获取用户名信息
    public static String extractUsername(String token) throws BusinessException {
        return extractClaim(token, Claims::getSubject);
    }

    // 从token中获取用户名信息
    public static String extractUsername(HttpServletRequest request) throws BusinessException {
        String token = request.getHeader(CommConst.TOKEN_KEY);
        return extractClaim(token, Claims::getSubject);
    }

    // 生成指定用户的JWT令牌
    public static String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, username);
    }

    // 从token中提取声明
    public static <T> T  extractClaim(String token, Function<Claims, T> claimsResolver) throws BusinessException {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    // 获取token中的所有声明
    private static Claims extractAllClaims(String token) throws BusinessException {
        try {
            return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
        }catch (Exception e)
        {
            e.printStackTrace();
            throw new BusinessException(CommonResponseDO.fail("-1","token识别失败"));
        }
    }

    // 创建JWT令牌，并设置过期时间等参数
    private static String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration))
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    // 验证token是否有效，例如检查是否过期等
    public static Boolean validateToken(String token) throws BusinessException {
        final String username = extractUsername(token);
        return (username != null && !isTokenExpired(token));
    }



    // 检查token是否过期
    private static Boolean isTokenExpired(String token) throws BusinessException {
        return extractExpiration(token).before(new Date());
    }


    // 从token中获取过期时间
    private  static Date extractExpiration(String token) throws BusinessException {
        return extractClaim(token, Claims::getExpiration);
    }
}
